<%
Class App_Helper_Tree

	Public dict, icon, nbsp

	Private Sub Class_Initialize()
		On Error Resume Next
		Set dict = AB.C.Dict()
		icon = array("│","├","└")
		nbsp = "&nbsp;"
		'nbsp = "　"
		On Error Goto 0
	End Sub

	Private Sub Class_Terminate()
		'..
	End Sub

	Public Function init(ByVal d)
		Dim i, j, f, v, dt, dd : Set dt = AB.C.Dict()
		If AB.C.IsDict(d) Then
			Set Me.dict = d
		ElseIf AB.C.IsRs(d) Then
			j = 0
			Do While Not d.Eof
				Set dd = AB.C.Dict()
				For i = 0 To d.Fields.Count-1 '字段序列
					f = LCase(d.Fields(i).Name) '字段名
					v = d.Fields(i).Value '字段值
					dd(f) = v
				Next
				j = j+1
				Set dt(j) = dd
				d.MoveNext
			Loop
			Set Me.dict = dt
		End If
		init = AB.C.IsDict(Me.dict)
	End Function

	Public Function get_parent(ByVal myid)
		Dim newdict, pid, id
		Set newdict = AB.C.Dict()
		If Not Me.dict.Exists(myid) Then
			get_parent = false
			Exit Function
		End If
		pid = Me.dict(myid)("pid")
		If AB.C.IsDict(Me.dict(pid)) Then pid = Me.dict(pid)("pid")
		If AB.C.IsDict(Me.dict) Then
			for each id in Me.dict
				if Me.dict(id)("pid")=pid Then
					Set newdict(id) = Me.dict(id)
				end if
			Next
		End If
		Set get_parent = newdict
	End Function

	Public Function get_child(ByVal myid)
		Dim newdict, pid, id
		Set newdict = AB.C.Dict()
		If AB.C.IsDict(Me.dict) Then
			for each id in Me.dict
				if Me.dict(id)("pid")=myid Then
					Set newdict(id) = Me.dict(id)
				end if
			Next
		End If
		Set get_child = newdict
	End Function

	public function get_tree(ByVal myid)
		Set get_tree = get_tree__("", myid, "")
	end function

	Private Function get_tree__(ByRef dtree, ByVal myid, ByVal adds)
		Dim id, number, total : number = 1
		Dim spacer, j, k
		If Not ab.c.isdict(dtree) Then Set dtree = AB.C.Dict()
		Dim child : Set child = Me.get_child(myid)
		if ab.c.isdict(child) then
		    total = child.count
			for each id in child
				j="" : k=""
				if number=total then
					j = j & Me.icon(2)
				else
					j = j & Me.icon(1)
					k = AB.C.IIF(adds<>"", Me.icon(0), "")
				end if
				spacer = AB.C.IIF(adds<>"", adds & j, "")
				dtree(id) = spacer
				Call get_tree__(dtree, id, adds & k & Me.nbsp)
				number = number + 1
			next
		end if
		Set get_tree__ = dtree
	End Function

	'调用方法： AB.Trace App.Helper("tree").getTypes("", 0, 0)
	Public Function getTypes(ByRef dtree, ByVal pid, ByVal deep)
		Set getTypes = getTypes__(dtree, pid, deep, 0)
	End Function

	Private Function getTypes__(ByRef types, ByVal pid, ByVal deep, ByVal path)
		Dim sql, rs, d, i, f, v, str, j, k, num, total, spacer
		If Not ab.c.isdict(types) Then Set types = AB.C.Dict()
		pid = AB.C.IIF(AB.C.IsNum(pid),CLng(pid),0)
		deep = AB.C.IIF(AB.C.IsNum(deep),CLng(deep),0)
		path = AB.C.IIF(AB.C.IsNum(path),CLng(path),0)
		sql = "select * from @menu where pid = "& pid &" order by ordid, id"
		num = 0
		Set rs = App.Dao.Query(sql)
		Do While Not rs.eof
			If deep>0 And path+1>deep Then Exit Do
			Set d = AB.C.Dict()
			j = ""
			total = rs.RecordCount
			num = num+1
			If checkTypes__(num, total) Then
				j = Me.icon(2)
				k = Me.icon(0)
			Else
				j = Me.icon(1)
				k = Me.icon(0)
			End If
			spacer = AB.C.StrRepeat(Me.nbsp & k, path-1) & (Me.nbsp & j)
			If path=0 Then spacer = ""
			'str = AB.C.StrRepeat(Me.nbsp, path)
			For i = 0 To rs.Fields.Count-1
				f = rs.Fields(i).Name
				v = rs.Fields(i).Value
				d(f) = v
			Next
			d("tree_spacer") = spacer
			types.add "id_"&rs("id"), d
			Call getTypes__(types,rs("id"),deep,path+1)
			rs.MoveNext
		Loop
		Set getTypes__ = types
	End Function

	Private Function checkTypes__(ByVal num, Byval total)
		Dim b : b = False
		If CLng(num) = CLng(total) Then
			b = True
		End if
		checkTypes__ = b
	End Function

	'调用方法： AB.Trace App.Helper("tree").get_tree0(Rs, "pid", "id", 0, "")
	Public Function get_tree0(Rs, pkey, idkey, pid, sort)
		On Error Resume Next
		'On Error Goto 0
		Dim tRs, oTree, i, j, f, v, a, b
		pid = AB.C.IIF(Trim(pid)="",0,CLng(pid))
		pkey = AB.C.IIF(Trim(pkey)="",0,"pid")
		idkey = AB.C.IIF(Trim(idkey)="",0,"id")
		AB.Use "A"
		If AB.C.IsRs(Rs) And Not AB.C.IsNul(Rs) Then
			Set tRs = App.Dao.CloneRs(Rs)
			Set oTree = AB.C.NewRs()
			oTree.CursorLocation = 1 
			oTree.CursorType = 1
			For i = 0 To tRs.Fields.Count-1
				f = tRs.Fields(i).Name
				v = tRs.Fields(i).Value
				oTree.Fields.Append tRs.Fields(i).Name, tRs.Fields(i).Type, tRs.Fields(i).DefinedSize, tRs.Fields(i).Attributes
			Next
			oTree.Fields.Append "SortField", 5, 10
			oTree.Fields.Append "TreeField", 203, 1500
			oTree.Open
			i = 0
			Do While Not tRs.eof
				a = Array()
				b = Array()
				For j = 0 To tRs.Fields.Count-1
					f = tRs.Fields(j).Name
					v = tRs.Fields(j).Value
					'v = AB.C.IIF(AB.C.isNul(v),"",v)
					a = AB.A.Push(a, f)
					b = AB.A.Push(b, v)
				Next
				a = AB.A.Push(a, "sort_field") : b = AB.A.Push(b, i)
				a = AB.A.Push(a, "tree_field") : b = AB.A.Push(b, "")
				oTree.AddNew a, b
				oTree.Update()
				tRs.MoveNext()
			Loop
			oTree.MoveFirst()
			Rs.MoveFirst()
			i = 0
			Do While Not oTree.eof
				v = oTree.Fields(pkey).Value
				If CBool(v=0) Then
					i = i+1
					oTree("sort_field") = i
				End If
				oTree.MoveNext()
			Loop
			oTree.UpdateBatch()
			oTree.Sort = AB.C.IIF(Trim(sort)="","sort_field ASC","sort_field ASC,"&sort)
			oTree.MoveFirst()
			If IsObject(oTree) Then Set get_tree = oTree Else get_tree = oTree
		Else
			If IsObject(Rs) Then Set get_tree = Rs Else get_tree = Rs
		End If
	End Function

End Class


''set rs = M("menu")().Top(0).Find("pid=0").Fetch()
'set rs = M("menu")().Top(0).Order("ordid,id").Fetch()

'dim tree
'set tree = App.Helper("tree")
'tree.init(rs)

''ab.trace rs
'ab.trace tree.get_child(0)
''ab.trace tree.get_parent(0)

'ab.trace tree.get_tree(0)
%>